package com.eshop.logging.aspect;

import cn.hutool.crypto.SecureUtil;
import org.slf4j.LoggerFactory;
import com.eshop.utils.SecurityUtils;
import org.aspectj.lang.annotation.AfterThrowing;
import com.eshop.utils.ThrowableUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Around;
import javax.servlet.http.HttpServletRequest;
import com.eshop.utils.StringUtils;
import com.eshop.utils.RequestHolder;
import com.eshop.logging.domain.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Pointcut;
import com.eshop.logging.service.LogService;
import org.slf4j.Logger;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAspect
{
    private static final Logger log;
    private final LogService logService;
    ThreadLocal<Long> currentTime;
    
    public LogAspect(final LogService logService) {
        this.currentTime = new ThreadLocal<Long>();
        this.logService = logService;
    }
    
    @Pointcut("@annotation(com.eshop.logging.aop.log.Log)")
    public void logPointcut() {
    }
    
    @Around("logPointcut()")
    public Object logAround(final ProceedingJoinPoint joinPoint) throws Throwable {
        this.currentTime.set(System.currentTimeMillis());
        final Object result = joinPoint.proceed();
        final Log log = new Log("INFO", System.currentTimeMillis() - this.currentTime.get());
        this.currentTime.remove();
        final HttpServletRequest request = RequestHolder.getHttpServletRequest();
        this.logService.save(this.getUsername(), StringUtils.getIp(RequestHolder.getHttpServletRequest()), joinPoint, log, this.getUid());
        return result;
    }
    
    @AfterThrowing(pointcut = "logPointcut()", throwing = "e")
    public void logAfterThrowing(final JoinPoint joinPoint, final Throwable e) {
        final Log log = new Log("ERROR", System.currentTimeMillis() - this.currentTime.get());
        this.currentTime.remove();
        log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes());
        final HttpServletRequest request = RequestHolder.getHttpServletRequest();
        this.logService.save(this.getUsername(), StringUtils.getIp(RequestHolder.getHttpServletRequest()), (ProceedingJoinPoint)joinPoint, log, this.getUid());
    }
    
    public String getUsername() {
        try {
            return SecurityUtils.getUsername();
        }
        catch (Exception e) {
            return "";
        }
    }
    
    public Long getUid() {
        try {
            //这个是调用的项目本身工具类获取的UserId
            return SecurityUtils.getUserId();
        }
        catch (Exception e) {
            return 0L;
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)LogAspect.class);
    }
}
